package zhanglu.family.socket.demo.busdemo.client1;

import java.util.ArrayList;
import java.util.List;

import zhanglu.family.socket.bean.busbean.BusMsgBean;
import zhanglu.family.socket.textline.busclient.BusClientHandler;
import zhanglu.family.socket.textline.busclient.BusTCPClient;
import zhanglu.family.socket.textline.factory.INetSocketFactory;
import zhanglu.family.socket.textline.factory.impl.NetSocketFactory;

/**
 * @author zhanglu
 * @date 2017年4月1日
 */
public class ClientManager {
    protected BusTCPClient    client;                                      // 客户端
    private String            ip                  = "127.0.0.1";           // ip
    private int               port                = 8888;                  // 端口
    private long              sessionSequence     = 592886931L;            // 此客户端的身份
    private long              sendSessionSequence = 1;                     // 用于发送同步请求的时候的身份证，每次加1.超出限制归0即可。

    private INetSocketFactory factory             = new NetSocketFactory(); // 获取实例工厂

    private ClientManager() {
    }

    private static ClientManager manager = null;

    public static ClientManager getInstance() {
        if (manager == null) {
            manager = new ClientManager();
        }
        return manager;
    }

    /**
     * 启动异步消息客户端,用一个线程专门维护异步消息。同步消息直接发送即可
     */
    public void startUp() {

        final List<String> classPath = new ArrayList<String>();
        classPath.add("zhanglu.family.socket.demo.busdemo.client1.handler.ClientHandlerDemo1");
        classPath.add("zhanglu.family.socket.demo.busdemo.client1.handler.ClientHandlerDemo2");

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    client = factory.getBusTCPClient(ip, port);
                    client.startClient(new BusClientHandler(client, classPath, false), sessionSequence);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 异步发送消息
     * 
     * @param headId
     *            协议号。标示具体某条协议
     * @param seqId
     *            消息流水号，标示消息唯一
     * @param targetSession
     *            目标人
     * @param bean
     *            消息体
     */
    public void post(long headId, long seqId, long targetSession, Object bean) {
        client.post(headId, seqId, targetSession, bean);
    }

    /**
     * 异步发送消息(注解)
     * 
     * @param t
     *            带有注解的实体类,即发送类
     * @param seqId
     *            异步消息流水号
     * @param bean
     *            消息文本
     */
    public void post(Class<?> t, long seqId, Object bean) {
        client.post(t, seqId, bean);
    }

    /**
     * 同步发送消息(长连接)
     * 
     * @param targetSession
     *            目标人
     * @param secondTimeout
     *            超时时间秒
     * @param bean
     *            消息文本
     * @return
     */
    public BusMsgBean sendLong(long targetSession, int secondTimeout, Object bean) {
        return client.send(targetSession, secondTimeout, bean);
    }

    /**
     * 同步发送消息(短连接)
     * 
     * 同步消息因为发送后直接拿数据，多数可以作为短连接使用，这个方法是短连接发送同步数据
     * 
     * @param targetSession
     *            目标人
     * @param secondTimeout
     *            超时时间秒
     * @param bean
     *            消息文本
     * @return
     */
    public BusMsgBean send(long targetSession, int secondTimeout, Object bean) {

        long seqId = sendSessionSequence;// 这里接一下，然后马上进行下面++操作，防止并发

        if (sendSessionSequence >= Long.MAX_VALUE) {
            sendSessionSequence = 1;
        }

        sendSessionSequence++;

        BusTCPClient client = new BusTCPClient(ip, port);
        try {
            client.startClient(new BusClientHandler(client, null, true), seqId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        BusMsgBean resultMsg = client.send(targetSession, secondTimeout, bean);

        client.dispose();

        return resultMsg;
    }
}
